import { View, Text, Button } from '@tarojs/components'
import { useState, useEffect, useRef } from 'react'
import Taro from '@tarojs/taro'
import './index.less'

export default function STTComponent({ visible, onClose }) {
  // 状态管理
  const [isConnected, setIsConnected] = useState(false)
  const [isConnecting, setIsConnecting] = useState(false)
  const [isRecording, setIsRecording] = useState(false)
  const [sessionId, setSessionId] = useState('')
  const [transmissionStatus, setTransmissionStatus] = useState('等待连接...')
  const [results, setResults] = useState([])
  const [interimResult, setInterimResult] = useState('')
  const [logs, setLogs] = useState([])
  const [errorMessage, setErrorMessage] = useState('')

  // WebSocket和音频相关引用
  const wsRef = useRef(null)
  const audioContextRef = useRef(null)
  const isRecordingRef = useRef(false)

  // WebSocket服务器配置
  const WS_URL = 'wss://www.yzyt.xyz/ws/stt'

  // 添加日志
  const addLog = (message) => {
    const timestamp = new Date().toLocaleTimeString()
    setLogs(prev => [{ time: timestamp, message }, ...prev.slice(0, 19)]) // 保留最新20条
  }

  // 显示错误
  const showError = (message) => {
    setErrorMessage(message)
    setTimeout(() => setErrorMessage(''), 5000)
  }

  // 更新连接状态
  const updateConnectionStatus = (status) => {
    switch (status) {
      case 'disconnected':
        setIsConnected(false)
        setIsConnecting(false)
        setTransmissionStatus('等待连接...')
        break
      case 'connecting':
        setIsConnected(false)
        setIsConnecting(true)
        setTransmissionStatus('连接中...')
        break
      case 'connected':
        setIsConnected(true)
        setIsConnecting(false)
        setTransmissionStatus('已连接，准备录音')
        break
      case 'recording':
        setIsRecording(true)
        setTransmissionStatus('传输音频数据...')
        break
    }
  }

  // 连接WebSocket
  const connectToServer = () => {
    if (wsRef.current && wsRef.current.readyState !== WebSocket.CLOSED) {
      addLog('连接已存在')
      return
    }

    updateConnectionStatus('connecting')
    addLog('正在连接到WebSocket服务器...')

    wsRef.current = new WebSocket(WS_URL)

    wsRef.current.onopen = () => {
      updateConnectionStatus('connected')
      addLog('已成功连接到服务器')
      setErrorMessage('')
    }

    wsRef.current.onmessage = (event) => {
      try {
        const message = JSON.parse(event.data)
        addLog(`收到消息: ${event.data}`)

        if (message.type === 'session') {
          setSessionId(message.sessionId)
          addLog(`会话已创建: ${message.sessionId}`)
        } else if (message.type === 'result') {
          displayResult(message.text, message.final)
        }
      } catch (e) {
        addLog(`收到无法解析的消息: ${event.data}`)
      }
    }

    wsRef.current.onerror = (error) => {
      showError('WebSocket连接错误')
      addLog('连接错误')
    }

    wsRef.current.onclose = (event) => {
      if (event.code === 1000) {
        addLog('连接已正常关闭')
      } else {
        addLog(`连接已关闭，代码: ${event.code}`)
      }

      updateConnectionStatus('disconnected')
      if (isRecordingRef.current) {
        stopRecording()
      }
      setTransmissionStatus('连接已关闭')
    }
  }

  // 开始录音
  const startRecording = async () => {
    if (isRecordingRef.current) return

    if (!wsRef.current || wsRef.current.readyState !== WebSocket.OPEN) {
      addLog('错误: WebSocket尚未连接')
      return
    }

    updateConnectionStatus('recording')
    addLog('开始录音...')

    try {
      // 在H5环境中获取用户音频流
      const stream = await navigator.mediaDevices.getUserMedia({
        audio: {
          sampleRate: 16000,
          channelCount: 1,
          echoCancellation: true,
          noiseSuppression: true
        }
      })

      // 创建AudioContext
      audioContextRef.current = new (window.AudioContext || window.webkitAudioContext)({
        sampleRate: 16000
      })

      // 创建媒体流源
      const source = audioContextRef.current.createMediaStreamSource(stream)

      // 创建处理器节点
      const processor = audioContextRef.current.createScriptProcessor(4096, 1, 1)

      // 音频处理逻辑
      processor.onaudioprocess = (event) => {
        if (!isRecordingRef.current) return

        const inputData = event.inputBuffer.getChannelData(0)
        const outputData = new Int16Array(inputData.length)
        
        for (let i = 0; i < inputData.length; i++) {
          outputData[i] = Math.max(-32768, Math.min(32767, inputData[i] * 32767))
        }

        // 通过WebSocket发送数据
        if (wsRef.current && wsRef.current.readyState === WebSocket.OPEN) {
          wsRef.current.send(outputData.buffer)
        }
      }

      // 连接处理链
      source.connect(processor)
      processor.connect(audioContextRef.current.destination)

      isRecordingRef.current = true
    } catch (err) {
      addLog('录音启动失败: ' + err.message)
      showError('无法访问麦克风: ' + err.message)
      stopRecording()
    }
  }

  // 停止录音
  const stopRecording = () => {
    if (!isRecordingRef.current) return

    isRecordingRef.current = false
    setIsRecording(false)
    addLog('录音已停止')

    // 关闭音频上下文
    if (audioContextRef.current) {
      audioContextRef.current.close().then(() => {
        audioContextRef.current = null
        addLog('AudioContext已关闭')
      })
    }

    updateConnectionStatus('connected')
    if (wsRef.current && wsRef.current.readyState === WebSocket.OPEN) {
      setTransmissionStatus('已停止传输，准备下次录音')
    }
  }

  // 显示识别结果
  const displayResult = (text, isFinal) => {
    if (!text.trim()) return

    if (isFinal) {
      setResults(prev => [{ text, time: new Date().toLocaleTimeString() }, ...prev])
      setInterimResult('')
    } else {
      setInterimResult(text)
    }
  }

  // 清除日志
  const clearLogs = () => {
    setLogs([])
    addLog('日志已清除')
  }

  // 组件卸载时清理资源
  useEffect(() => {
    return () => {
      if (wsRef.current) {
        wsRef.current.close()
      }
      if (audioContextRef.current) {
        audioContextRef.current.close()
      }
    }
  }, [])

  // 获取状态指示器类名
  const getStatusClass = () => {
    if (isRecording) return 'status-recording'
    if (isConnected) return 'status-connected'
    if (isConnecting) return 'status-connecting'
    return 'status-disconnected'
  }

  if (!visible) return null

  return (
    <View className='stt-container'>
      <View className='stt-header'>
        <Text className='stt-title'>语音识别测试客户端</Text>
        <Button className='close-btn' onClick={onClose}>×</Button>
      </View>

      {errorMessage && (
        <View className='error-panel'>
          <Text>{errorMessage}</Text>
        </View>
      )}

      <View className='control-panel'>
        <View className='status-bar'>
          <View className={`status-indicator ${getStatusClass()}`}></View>
          <Text className='status-text'>
            {isRecording ? '录音中...' : isConnected ? '已连接，准备录音' : isConnecting ? '连接中...' : '未连接'}
          </Text>
        </View>

        <View className='button-container'>
          <Button 
            className={`btn btn-primary ${isConnected ? 'btn-disabled' : ''}`}
            disabled={isConnected || isConnecting}
            onClick={connectToServer}
          >
            连接到服务器
          </Button>
          <Button 
            className={`btn btn-primary ${!isConnected || isRecording ? 'btn-disabled' : ''}`}
            disabled={!isConnected || isRecording}
            onClick={startRecording}
          >
            开始录音
          </Button>
          <Button 
            className={`btn btn-danger ${!isRecording ? 'btn-disabled' : ''}`}
            disabled={!isRecording}
            onClick={stopRecording}
          >
            停止录音
          </Button>
        </View>

        <View className='session-info'>
          <View className='info-item'>
            <Text>会话ID: </Text>
            <Text className='session-id'>{sessionId || '暂无'}</Text>
          </View>
          <View className='info-item'>
            <Text>传输状态: </Text>
            <Text>{transmissionStatus}</Text>
          </View>
        </View>
      </View>

      <View className='results-panel'>
        <Text className='panel-title'>识别结果</Text>
        <View className='interim-result'>
          <Text className='result-label'>(中间结果)</Text>
          <Text className='interim-text'>{interimResult}</Text>
        </View>
        <View className='results-list'>
          {results.map((result, index) => (
            <View key={index} className='result-item'>
              <Text className='result-time'>[{result.time}]</Text>
              <Text className='result-text'>{result.text}</Text>
            </View>
          ))}
        </View>
      </View>

      <View className='logs-panel'>
        <View className='logs-header'>
          <Text className='panel-title'>日志信息</Text>
          <Button className='btn btn-small' onClick={clearLogs}>清除日志</Button>
        </View>
        <View className='logs-content'>
          {logs.map((log, index) => (
            <View key={index} className='log-entry'>
              <Text className='log-time'>[{log.time}]</Text>
              <Text className='log-message'>{log.message}</Text>
            </View>
          ))}
        </View>
      </View>
    </View>
  )
}